package com.wkq.net

import com.wkq.net.callback.DataCallback
import com.wkq.net.callback.DataLoadingCallback
import com.wkq.net.model.BaseModel
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.functions.Consumer
import io.reactivex.rxjava3.schedulers.Schedulers
import retrofit2.HttpException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

/**
 * Retrofit 请求辅助类，采用双重检查锁定的单例模式管理 Retrofit 实例
 */
object RetrofitRequestHelper {
    /**
     * 创建引擎开始请求
     */
    fun <T> create( service: Class<T>,isHttpsPing: Boolean = false): T {
        return HttpConfig.getRetrofitInstance(isHttpsPing).create(service)
    }

    /**
     * 带加载回调的请求
     * @receiver Observable<BaseModel<T>>
     * @param dataCallback DataLoadingCallback<T>
     */
    fun <T> Observable<BaseModel<T>>.requestLoading(callback: DataLoadingCallback<T>): Disposable {
        val onNextConsumer: Consumer<BaseModel<T>> = Consumer { baseModel ->
            if (200 == baseModel.api_code) {
                callback.success(baseModel.data)
            } else {
                callback.onFail(baseModel.api_code, baseModel.api_msg)
            }
        }

        return this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(onNextConsumer, defaultErrorHandler(callback))
    }

    /**
     * Json转Bean类型的请求
     * @receiver Observable<BaseModel<T>>
     * @param dataCallback DataCallback<T>
     */
    fun <T> Observable<BaseModel<T>>.request(callback: DataCallback<T>): Disposable {
        val onNextConsumer: Consumer<BaseModel<T>> = Consumer { baseModel ->
            if (200 == baseModel.api_code) {
                callback.success(baseModel.data)
            } else {
                callback.onFail(baseModel.api_code, baseModel.api_msg)
            }
        }


        return this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(onNextConsumer, defaultErrorHandler(callback))

    }

    // data 需要用到 api_data 而不是data  特殊接口使用
    fun <T> Observable<BaseModel<T>>.requestApiData(callback: DataCallback<T>): Disposable {
        val onNextConsumer: Consumer<BaseModel<T>> = Consumer { baseModel ->
            if (200 == baseModel.api_code) {
                callback.success(baseModel.api_data)
            } else {
                callback.onFail(baseModel.api_code, baseModel.api_msg)
            }
        }

        return this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(onNextConsumer, defaultErrorHandler(callback))

    }

    /**
     * String 类型的请求  retrofit 处理请求不能以String形式返回结果 因为结果是LinkTreeMap形式返回的只能Any接收
     * @receiver Observable<T>
     * @param dataCallback DataCallback<T>
     */

    fun <T : Any> Observable<T>.requestSpecial(callback: DataCallback<T>): Disposable {
        val onNextConsumer: Consumer<T> = Consumer { baseModel ->
            callback.success(baseModel)
        }

        return this.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(onNextConsumer, defaultErrorHandler(callback))
    }

    /**
     * 异常的封装方法
     */
    private fun defaultErrorHandler(
        callback: DataCallback<*>
    ): Consumer<Throwable> {
        return Consumer { error ->
            val errorMessage = when (error) {
                is UnknownHostException -> "网络连接失败，请检查网络设置"
                is SocketTimeoutException -> "连接超时，请重试"
                is HttpException -> "服务器异常: ${error.message()}"
                else -> error.message ?: "未知错误"
            }
            callback.onFail(-1, errorMessage)
        }
    }

}